package xiaoa.java.netty;

import java.net.URI;

import java.util.List;


import java.util.Map;

import io.netty.buffer.ByteBuf;
import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.ChannelInboundHandlerAdapter;
import io.netty.handler.codec.http.HttpContent;
import io.netty.handler.codec.http.HttpResponse;
import io.netty.handler.codec.http.LastHttpContent;
import io.netty.util.ReferenceCountUtil;

/**
 * http 返回出来
 * @author xiaoa
 * @date 2017年7月25日 下午4:57:10
 * @version V1.0
 *
 */
public class HttpResponseHandler extends ChannelInboundHandlerAdapter {
	
	// http返回结果
	HttpResponseResult  result = null;
	
	// http工具类
	HttpClient client;
	
	URI uri ;
	
    public HttpResponseHandler(HttpResponseResult result ,HttpClient client , URI uri ) {

		 this.result = result;
		 this.client = client;
		 this.uri    = uri;
	}
	
	@Override
	public void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception {
		
		if (msg instanceof HttpResponse) {
			
			HttpResponse response = (HttpResponse) msg;

			List<Map.Entry<String, String>>  headresList =  response.headers().entries();
			
			for (Map.Entry<String, String>  h : headresList){
				result.handles.put(h.getKey(), h.getValue());
			}
			
			result.code = response.status().code();
			
			result.completeHandler();
			
		}
		if (msg instanceof HttpContent) {
			
			HttpContent content = (HttpContent) msg;
			ByteBuf buf = content.content();
			
			int bodyLength = ( result.body != null ?  result.body.length : 0);

			byte[] tempBs = new byte[buf.readableBytes() + bodyLength];

			if (tempBs.length != bodyLength){

				if ( bodyLength > 0){
					System.arraycopy(result.body , 0 , tempBs , 0 , bodyLength);
				}

				buf.readBytes(tempBs ,bodyLength , buf.readableBytes() );
				result.body = tempBs;
			}

			// 如果是最后一个，，释放客户端
			if(msg instanceof LastHttpContent){
				result.completeBody();
				client.release(ctx.channel(), uri);
			}
			
		}
		
		// 做最后的回收
		ReferenceCountUtil.release(msg);
	}

	@Override
    public void channelActive(ChannelHandlerContext ctx) throws Exception {
    	System.out.println("channelActive");
    }
	@Override
	 public void channelUnregistered(ChannelHandlerContext ctx) throws Exception {
		
		if (!result.isComplete()){
			exceptionCaught(ctx, new RuntimeException(" channelUnregistered "));
		}else{
			Log.debug(ctx.channel() + " is channelUnregistered");
		}
	};

    @Override
	public void exceptionCaught(ChannelHandlerContext ctx,Throwable cause) {

		Log.debug(ctx + " ： 异常");

		try {
			client.releaseAndClose(ctx.channel(), uri);//出现异常时关闭channel
		} catch (Exception e) {
			e.printStackTrace();
		}finally {
			result.exceptionClose(cause);
		}
		
	}


}
